package com.taotao.common.enums;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.Objects;

@Slf4j
@AllArgsConstructor
@NoArgsConstructor
public class EnumAtSerializer extends JsonSerializer<Object> implements ContextualSerializer {

    private String fieldName;
    private EnumField enumAt;

    @Override
    public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
            throws IOException {
        jgen.writeObject(value);

        Class<? extends CodeTextEnum> enumClass = enumAt.value();

        jgen.writeObjectField(fieldName + "_label", getDisplayName(enumClass, value));
    }


    private String getDisplayName(Class<? extends CodeTextEnum> enumClass, Object value) {
        try {
            //反射调用枚举的values方法
            CodeTextEnum[] values = (CodeTextEnum[]) enumClass.getMethod("values").invoke(new Object(), new Object[]{});
            if (null == values || 0 == values.length) {
                return null;
            }

            for (CodeTextEnum e : values) {
                if (Objects.equals(e.getCode(), value)) {
                    return e.getText();
                }
            }

        } catch (Exception e) {
            log.error("", e);
        }

        return null;
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if (beanProperty == null) {
            //为空直接跳过
            return serializerProvider.findNullValueSerializer(beanProperty);
        }


        EnumField enumAt = beanProperty.getAnnotation(EnumField.class);
        if (null == enumAt) {
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }

        return new EnumAtSerializer(beanProperty.getName(), enumAt);
    }
}